
// useCallback
// 作用：钩住组件属性中某些处理函数，创建这些函数对应在react原型链上的变量引用
// useCallback 第2个参数是处理函数中的依赖变量，只有当依赖变量发生改变时才会重新修改并创建新的一份处理函数
// REACT原型链简单理解为react定义的一块内存
// useCallback 是通过将获取函数在react原型链上的引用，当即将重新渲染的时候，用旧值的引用去替换旧值
// 配合react.memo,达到组件不必要的重新渲染

// 详细解释
// useCallBack可以将组件的某些处理函数挂载到react底层原型链上，并返回该处理函数的引用，当组件每次即将
// 重新渲染时，确保props中该处理函数为同一函数，跳过本次无意义的重新渲染，达到提高组件性能的目的，当然
// 前提是该组件在导出时使用了react.memo

// 基本用法
// useCallback(callback,deps)函数通常传入2个参数，第1个参数为我们定义的一个处理函数，通常为一个箭头函数
// 第2个参数为该处理函数中存在的依赖变量；凡是处理函数中有的数据变量都需要放入deps中，如果没有，即为[]


// 代码形式

//import Button from './button' // 引入我们自定义的一个组件<button>
//组件内部声明一个age变量
//const [age,setAge] = useState(34)

// 通过useCallback,将鼠标点击处理函数保存到react底层原型链中，并获取该函数的引用，将引用赋值给clickHandler
// const clickHandler = useCallback(() => {
//     setAge(age + 1)
// },[age]) // 由于该处理函数中使用到了age这个变量。因此useCallback的第2个参数中，需要将age添加进去
// 使用该处理函数，实例为使用该处理函数的react底层原型链上的引用
// return <button onClick={() => clickHandler}>add</button>

// 实际组件运用中，如果父组件只有1个子组件，其实完全没有必须使用useCallback
// 只有父组件同时有多个子组件时，才有必要去做性能优化，防止某一个子组件引发的重新渲染导致其他子组件跟着重新渲染

// 使用示例

// 若我们有一个自定组件button,代码如下
// import React from 'react'
// function Button ({label,clickHandler}) {
//     //为了方便我们查看该子组件是否被重新渲染，这里增加一行console.log代码
//     console.log(`rendering ... ${label}`);
//     return <button onClick={clickHandler}>{label}</button>;
// }
// export default React.memo(Button); //使用React.memo()包裹住要导出的组件

// 需求： 组件内部有2个变量age,salary；有2个自定义组件button，点击之后分别可以修改age,salary值
// import React,{useState,useCallBack,useEffect} from 'react'
// import Button from './button'
// function MyButton () {
//     const [age,setAge] = useState(34)
//     const [salary,setSalary] = useState(7000)
//      useEffect(() => {
//          document.title = `${Math.floor(Math.random()*10)}`
//      })
//     //使用useCallback()包裹住原来的处理函数
//      const clickHandle01 = useCallBack(() => {
//          setAge(age +1)
//      },[age])
//     //使用useCallback()包裹住原来的处理函数
//     const clickHandle02 = useCallBack(() => {
//         setSalary(salary +1)
//     },[salary])
//
//     return (
//         <div>
//             {age}-{salary}
//             <button lable='btn1' onClick={clickHandle01}>btn1</button>
//             <button lable='btn2' onClick={clickHandle02}>btn2</button>
//         </div>
//     )
// }

// 假设上面示例代码中，做以下修改：每个按钮上新增一个属性：random={Math.floor(Math.random()*100)}
// <Button label='Bt01' clickHandler={clickHandler01}></Button>
// <Button label='Bt02' clickHandler={clickHandler02}></Button>
// 修改为
// <Button label='Bt01' clickHandler={clickHandler01} random={Math.floor(Math.random()*100)}></Button>
// <Button label='Bt02' clickHandler={clickHandler02} random={Math.floor(Math.random()*100)}></Button>
// 那么请问，此时我们针对性能优化而使用的useCallback还有意义吗？
//
// 答：没有任何意义，虽然我们使用useCallback保证了每次clickHandler是相同的，
// 可是 random 的值每次却是随机不一样的，尽管子组件<Button>并没有使用到 random 这个值，
// 但是它的加入造成了 props 每次都不一样(其实是 props.random 不一样)，
// 结果就是子组件每一次都会被重新渲染。所以此时useCallback已经失去了存在的意义。

